<template>
  <view class="treeSelect">
    <view class="box">
      <view class="title">
        <text>{{ title }}</text>
        <view class="closeBut" @click="close">
          <image class="ico" :src="ico_choose"></image>
        </view>
      </view>
      <view class="con">
        <treeSelectOne
          @getChooseValue="getValue"
          @openTagChange="openTagChange"
          :checkStrictly="checkStrictly"
          :multiple="multiple"
          :data="listData"
          :allData="listData"
          :chooseMode="chooseMode"
          :showAllLevels="showAllLevels"
        ></treeSelectOne>
      </view>
      <view class="but">
        <button @click="save" class="but yes">{{ submitText }}</button>
        <button @click="close" class="but no">{{ cancelText }}</button>
      </view>
    </view>
  </view>
</template>

<script>
import treeSelectOne from "./oneselect.vue";
import ico_choose from "@/static/images/ico_choose.png";

export default {
  data() {
    return {
      chooseIds: [],
      chooseItems: [],
      listData: [],
      ico_choose,
    };
  },
  props: {
    // 树（Tree）是否显示。
    show: Boolean,
    // 树（Tree）解构数据。
    data: Array,
    // 树（Tree），需要回显的数据，id的数组。注意multiple值需与回显值匹配。
    id: {
      type: Array,
      default: function () {
        return [];
      },
    },
    // 是否严格的遵守父子节点不互相关联（true: 每一级都能选，false: 只能选最后一级）
    checkStrictly: {
      type: Boolean,
      default: false,
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false,
    },
    // 是否返回完整路径数据集
    showAllLevels: {
      type: Boolean,
      default: true,
    },
    // 选择器标题
    title: {
      type: String,
      default: "部门选择",
    },
    // 确定按钮文字
    submitText: {
      type: String,
      default: "确定",
    },
    // 取消按钮文字
    cancelText: {
      type: String,
      default: "取消",
    },
    // 选择模式，默认line，勾选模式ico
    chooseMode: {
      type: String,
      default: "line",
    },
  },
  components: {
    treeSelectOne,
  },
  emit: ["getChooseValue", '"close"'],
  watch: {
    // 根据回显id集,回显数据
    id() {
      this.chooseIds = this.id;
      this.chooseItems = [];
      // 单选
      if (!this.multiple) {
        const chooseItem = this.changeValue(
          this.listData,
          JSON.parse(JSON.stringify(this.chooseIds)),
          []
        );
        this.chooseItems = chooseItem;
      } else {
        const chooseIds = JSON.parse(JSON.stringify(this.chooseIds));
        chooseIds.forEach((item) => {
          const chooseItem = this.changeValue(this.listData, item, []);
          this.chooseItems.push(chooseItem);
        });
      }
    },
    data(newValue, oldValue) {
      this.listData = newValue;
    },
  },
  mounted() {
    // if (this.multiple) {
    // 	this.chooseIds = [];
    // 	this.chooseItems = [];
    // }
    this.initValue(this.data);
    this.listData = this.data;
  },
  methods: {
    // 推完整路径，解决小程序，展开后选中父节点自动收起问题。
    openTagChange(ids, openTag) {
      this.openTagDg(this.listData, ids[ids.length - 1], openTag);
    },
    // 递归改值
    // data：树数据
    // id：展开或收起的对象id
    // openTag：状态值
    openTagDg(data, id, openTag) {
      data.forEach((item, i) => {
        if (item.id === id) {
          item.openTag = openTag;
        }

        if (item.children !== undefined) {
          this.openTagDg(item.children, id, openTag);
        }
      });
    },
    // 关闭
    close() {
      this.$emit("close", false);
      // this.chooseIds = [];
      // this.chooseItems = [];
    },
    // 选中的值
    save() {
      if (this.chooseIds.length > 0) {
        this.$emit("getChooseValue", this.chooseIds, this.chooseItems); // 继续向上传递
        this.close();
      } else {
        uni.showToast({
          title: "您还没有选择任何项目。",
          duration: 2000,
          icon: "none",
        });
      }
    },
    // 获取tree选择的结果
    // ids的数组
    // oldChoose历史选中状态
    getValue(ids, oldChoose) {
      this.chooseItems = [];
      // 单选
      if (!this.multiple) {
        this.chooseIds = ids;
        const chooseItem = this.changeValue(
          this.listData,
          JSON.parse(JSON.stringify(this.chooseIds)),
          []
        );
        this.chooseItems = chooseItem;
      } else {
        if (!oldChoose) {
          this.chooseIds.push(ids);
        } else {
          const nums = this.chooseIds.length;
          const tempids = ids.toString();
          let index = -1;
          for (let i = 0; i < nums; i++) {
            const temp = this.chooseIds[i].toString();
            if (temp === tempids) {
              index = i;
              break;
            }
          }
          if (index > -1) {
            this.chooseIds.splice(index, 1);
          }
        }
        this.multipleDataInit(this.listData);
        const chooseIds = JSON.parse(JSON.stringify(this.chooseIds));
        if (chooseIds.length === 0) {
          this.chooseItems = [];
        } else {
          chooseIds.forEach((item) => {
            const chooseItem = this.changeValue(this.listData, item, []);
            this.chooseItems.push(chooseItem);
          });
        }
      }
    },
    // 多选模式，一个都没选的重置
    multipleDataInit(data) {
      data.forEach((item, i) => {
        item.choose = false;
        if (item.children !== undefined) {
          this.multipleDataInit(item.children);
        }
      });
    },
    // 递归改值
    // data：树数据
    // chooseIds：选择的树id数据集
    // chooseItem：选择的树item数据集
    changeValue(data, chooseIds, chooseItem) {
      data.forEach((item, i) => {
        // 单选
        if (!this.multiple) {
          item.choose =
            chooseIds[chooseIds.length - 1] === item.id
              ? item.choose
                ? false
                : true
              : false;
        }
        // 多选，到达选中项
        if (this.multiple && chooseIds[chooseIds.length - 1] === item.id) {
          // console.log(oldChoose)
          item.choose = true;
        }
        // 小程序选择bug优化。
        if (chooseIds[0] === item.id) {
          chooseItem.push(item);
          chooseIds.splice(0, 1);
          // item.openTag = true;
        }

        if (item.children !== undefined) {
          chooseItem = this.changeValue(item.children, chooseIds, chooseItem);
        }
      });
      return chooseItem;
    },
    // 初始化
    initValue(data) {
      data.forEach((item, i) => {
        item.choose = false;
        item.openTag = false;
        if (item.children !== undefined) {
          this.initValue(item.children);
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.treeSelect {
  width: 100%;
  height: 100vh;
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 101;
  background-color: rgba(0, 0, 0, 0.3);
  .box {
    width: 700upx;
    height: 80vh;
    background-color: #fff;
    border-radius: 10upx;
    position: absolute;
    top: 10vh;
    left: 25upx;
    .title {
      border-bottom: 2upx solid #eee;
      height: 90upx;
      line-height: 90upx;
      padding-left: 20upx;
      font-size: 32upx;
      font-weight: 600;
      .closeBut {
        width: 90upx;
        height: 90upx;
        float: right;
        .ico {
          width: 30upx;
          height: 30upx;
          margin: 30upx;
        }
      }
    }
    .con {
      width: 100%;
      height: calc(100% - 190upx);
      padding: 20upx;
      box-sizing: border-box;
      overflow-y: auto;
    }
    .but {
      height: 100upx;
      .but {
        width: 120upx;
        height: 60upx;
        line-height: 60upx;
        text-align: center;
        border-radius: 10upx;
        margin: 20upx;
        float: right;
        font-size: 26upx;
        &.yes {
          background-color: #1890ff;
          color: #fff;
        }
        &.no {
          background-color: #fff;
          border: 2upx solid #ccc;
          color: #333;
        }
      }
    }
  }
}
</style>
